﻿using Fishing.Abstractions;
using Fishing.Common;
using Fishing.View;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Input;

namespace Fishing.Converter
{
    class KeyGestureModifiersValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is KeyGesture keyGesture)
            {
                var modifiers = keyGesture.Modifiers;

                var index = int.Parse((string)parameter);

                return modifiers switch
                {
                    ModifierKeys.None => throw new NotImplementedException(),
                    ModifierKeys.Control => index == 3 || index == 6 || index == 9,
                    ModifierKeys.Alt => index == 4 || index == 7 || index == 10,
                    ModifierKeys.Shift => index == 5 || index == 8 || index == 11,
                    ModifierKeys.Control | ModifierKeys.Alt => index == 3 || index == 6 || index == 4 || index == 7 || index == 9 || index == 10,
                    ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift => true,
                    ModifierKeys.Control | ModifierKeys.Shift => index == 3 || index == 6 || index == 5 || index == 8 || index == 9 || index == 11,
                    ModifierKeys.Alt | ModifierKeys.Shift => index == 4 || index == 7 || index == 5 || index == 8 || index == 10 || index == 11,
                    _ => throw new NotImplementedException(),
                };
            }

            return string.Empty;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var index = int.Parse((string)parameter);

            var settingsService = App.Services.GetRequiredService<ISettingsService>();

            if (index < 6)
            {
                var actualIndex = index - 3;

                var oldKeyGesture = settingsService.Settings.QuickUpdateKeyBinding;
                var newKeyGesture = RecreateKeyGesture((bool)value, actualIndex, oldKeyGesture);

                if (settingsService.Settings.TrySetKeyBingding(KeyBindingMap.QuickUpdate, newKeyGesture))
                {
                    return newKeyGesture;
                }

                var snackbar = App.Services.GetRequiredService<IViewProvider>().GetView<SettingsView>().SnackbarThree;

                snackbar.MessageQueue?.Enqueue("快捷键冲突", null, null, null, false, true, TimeSpan.FromSeconds(1));

                return oldKeyGesture;
            }
            else if (index < 9)
            {
                var actualIndex = index - 6;

                var oldKeyGesture = settingsService.Settings.ForceQuitKeyBinding;
                var newKeyGesture = RecreateKeyGesture((bool)value, actualIndex, oldKeyGesture);

                if (settingsService.Settings.TrySetKeyBingding(KeyBindingMap.ForceQuit, newKeyGesture))
                {
                    return newKeyGesture;
                }

                var snackbar = App.Services.GetRequiredService<IViewProvider>().GetView<SettingsView>().SnackbarThree;

                snackbar.MessageQueue?.Enqueue("快捷键冲突", null, null, null, false, true, TimeSpan.FromSeconds(1));

                return oldKeyGesture;
            }
            else
            {
                var actualIndex = index - 9;

                var oldKeyGesture = settingsService.Settings.ExhaleKeyBinding;
                var newKeyGesture = RecreateKeyGesture((bool)value, actualIndex, oldKeyGesture);

                if (settingsService.Settings.TrySetKeyBingding(KeyBindingMap.Exhale, newKeyGesture))
                {
                    return newKeyGesture;
                }

                var snackbar = App.Services.GetRequiredService<IViewProvider>().GetView<SettingsView>().SnackbarThree;

                snackbar.MessageQueue?.Enqueue("快捷键冲突", null, null, null, false, true, TimeSpan.FromSeconds(1));

                return oldKeyGesture;
            }
        }

        private static KeyGesture RecreateKeyGesture(bool isChecked, int parameter, KeyGesture oldKetGesture)
        {
            var modifierKey = MapModifierKeys(parameter);

            if (isChecked)
            {
                return new KeyGesture(oldKetGesture.Key, oldKetGesture.Modifiers | modifierKey);
            }

            return new KeyGesture(oldKetGesture.Key, oldKetGesture.Modifiers & ~modifierKey);
        }

        private static ModifierKeys MapModifierKeys(int parameter)
        {
            if (parameter == 0)
            {
                return ModifierKeys.Control;
            }
            else if (parameter == 1)
            {
                return ModifierKeys.Alt;
            }

            return ModifierKeys.Shift;
        }
    }
}